﻿using System;
using UnityEngine;

public class PinchRotationSample : SampleBase
{
    private InputMode inputMode = InputMode.PinchAndRotation;
    public Rect inputModeButtonRect;
    private Material originalMaterial;
    public Material pinchAndRotationMaterial;
    private bool pinching;
    public Material pinchMaterial;
    public float pinchScaleFactor = 0.02f;
    private bool rotating;
    public Material rotationMaterial;
    public Transform target;

    private void FingerGestures_OnPinchBegin(Vector2 fingerPos1, Vector2 fingerPos2)
    {
        if (this.PinchAllowed)
        {
            this.Pinching = true;
        }
    }

    private void FingerGestures_OnPinchEnd(Vector2 fingerPos1, Vector2 fingerPos2)
    {
        if (this.Pinching)
        {
            this.Pinching = false;
        }
    }

    private void FingerGestures_OnPinchMove(Vector2 fingerPos1, Vector2 fingerPos2, float delta)
    {
        if (this.Pinching)
        {
            Transform transform = this.target.transform;
            transform.localScale += (Vector3) ((delta * this.pinchScaleFactor) * Vector3.one);
        }
    }

    private void FingerGestures_OnRotationBegin(Vector2 fingerPos1, Vector2 fingerPos2)
    {
        if (this.RotationAllowed)
        {
            base.UI.StatusText = "Rotation gesture started.";
            this.Rotating = true;
        }
    }

    private void FingerGestures_OnRotationEnd(Vector2 fingerPos1, Vector2 fingerPos2, float totalRotationAngle)
    {
        if (this.Rotating)
        {
            base.UI.StatusText = "Rotation gesture ended. Total rotation: " + totalRotationAngle;
            this.Rotating = false;
        }
    }

    private void FingerGestures_OnRotationMove(Vector2 fingerPos1, Vector2 fingerPos2, float rotationAngleDelta)
    {
        if (this.Rotating)
        {
            base.UI.StatusText = "Rotation updated by " + rotationAngleDelta + " degrees";
            this.target.Rotate(0f, 0f, rotationAngleDelta);
        }
    }

    protected override string GetHelpText()
    {
        return "This sample demonstrates how to use the two-fingers Pinch and Rotation gesture events to control the scale and orientation of a rectangle on the screen\r\n\r\n- Pinch: move two fingers closer or further apart to change the scale of the rectangle\r\n- Rotation: twist two fingers in a circular motion to rotate the rectangle\r\n\r\n";
    }

    private void OnDisable()
    {
        FingerGestures.OnRotationBegin -= new FingerGestures.RotationBeginEventHandler(this.FingerGestures_OnRotationBegin);
        FingerGestures.OnRotationMove -= new FingerGestures.RotationMoveEventHandler(this.FingerGestures_OnRotationMove);
        FingerGestures.OnRotationEnd -= new FingerGestures.RotationEndEventHandler(this.FingerGestures_OnRotationEnd);
        FingerGestures.OnPinchBegin -= new FingerGestures.PinchEventHandler(this.FingerGestures_OnPinchBegin);
        FingerGestures.OnPinchMove -= new FingerGestures.PinchMoveEventHandler(this.FingerGestures_OnPinchMove);
        FingerGestures.OnPinchEnd -= new FingerGestures.PinchEventHandler(this.FingerGestures_OnPinchEnd);
    }

    private void OnEnable()
    {
        FingerGestures.OnRotationBegin += new FingerGestures.RotationBeginEventHandler(this.FingerGestures_OnRotationBegin);
        FingerGestures.OnRotationMove += new FingerGestures.RotationMoveEventHandler(this.FingerGestures_OnRotationMove);
        FingerGestures.OnRotationEnd += new FingerGestures.RotationEndEventHandler(this.FingerGestures_OnRotationEnd);
        FingerGestures.OnPinchBegin += new FingerGestures.PinchEventHandler(this.FingerGestures_OnPinchBegin);
        FingerGestures.OnPinchMove += new FingerGestures.PinchMoveEventHandler(this.FingerGestures_OnPinchMove);
        FingerGestures.OnPinchEnd += new FingerGestures.PinchEventHandler(this.FingerGestures_OnPinchEnd);
    }

    private void OnGUI()
    {
        string str;
        InputMode rotationOnly;
        SampleUI.ApplyVirtualScreen();
        InputMode inputMode = this.inputMode;
        if (inputMode == InputMode.PinchOnly)
        {
            str = "Pinch Only";
            rotationOnly = InputMode.RotationOnly;
        }
        else if (inputMode == InputMode.RotationOnly)
        {
            str = "Rotation Only";
            rotationOnly = InputMode.PinchAndRotation;
        }
        else
        {
            str = "Pinch + Rotation";
            rotationOnly = InputMode.PinchOnly;
        }
        if (GUI.Button(this.inputModeButtonRect, str))
        {
            this.inputMode = rotationOnly;
        }
    }

    protected override void Start()
    {
        base.Start();
        base.UI.StatusText = "Use two fingers anywhere on the screen to rotate and scale the green object.";
        this.originalMaterial = this.target.renderer.sharedMaterial;
    }

    private void UpdateTargetMaterial()
    {
        Material pinchAndRotationMaterial;
        if (this.pinching && this.rotating)
        {
            pinchAndRotationMaterial = this.pinchAndRotationMaterial;
        }
        else if (this.pinching)
        {
            pinchAndRotationMaterial = this.pinchMaterial;
        }
        else if (this.rotating)
        {
            pinchAndRotationMaterial = this.rotationMaterial;
        }
        else
        {
            pinchAndRotationMaterial = this.originalMaterial;
        }
        this.target.renderer.sharedMaterial = pinchAndRotationMaterial;
    }

    public bool PinchAllowed
    {
        get
        {
            return ((this.inputMode == InputMode.PinchOnly) || (this.inputMode == InputMode.PinchAndRotation));
        }
    }

    private bool Pinching
    {
        get
        {
            return this.pinching;
        }
        set
        {
            if (this.pinching != value)
            {
                this.pinching = value;
                this.UpdateTargetMaterial();
            }
        }
    }

    private bool Rotating
    {
        get
        {
            return this.rotating;
        }
        set
        {
            if (this.rotating != value)
            {
                this.rotating = value;
                this.UpdateTargetMaterial();
            }
        }
    }

    public bool RotationAllowed
    {
        get
        {
            return ((this.inputMode == InputMode.RotationOnly) || (this.inputMode == InputMode.PinchAndRotation));
        }
    }

    public enum InputMode
    {
        PinchOnly,
        RotationOnly,
        PinchAndRotation
    }
}

